// crc
package crcutil

//计算dat的Modbus协议的crc校验码，并追加到结尾
//返回：<dat><crc16_低><crc16_高>
func AppendModbusCrc16(dat []byte) []byte {
	crc := Crc16_A001(dat)
	h, l := byte(crc>>8), byte(crc)
	return append(dat, l, h)
}

//计算modbus的crc16校验码，生成多项式为A001
func Crc16_A001(dat []byte) uint16 {
	var crc_reg, crc_gen uint32
	crc_reg, crc_gen = 0xFFFF, 0xA001

	for i, l := 0, len(dat); i < l; i++ {
		crc_reg = (uint32(dat[i]) & 0xff) ^ crc_reg
		for j := 8; j > 0; j-- {
			if crc_reg&0x01 == 1 {
				crc_reg >>= 1
				crc_reg ^= crc_gen
			} else {
				crc_reg >>= 1
			}
		}
	}
	return uint16(crc_reg)
}
